package com.face.service;

import com.face.common.Page;
import com.face.dao.AccountDao;
import com.face.entity.Account;
import com.face.entity.Role;
import com.face.entity.Shop;
import com.face.exception.AccountExistException;
import com.face.exception.EmailExistException;
import com.face.exception.NoAccountException;
import com.face.exception.OldPasswordErrorException;
import com.face.form.ChangePasswordForm;
import com.face.util.MailUtil;
import com.face.util.ThreadUtil;
import com.face.wrapper.AccountWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.mail.MessagingException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
public class AccountService {
    @Autowired
    private AccountDao accountDao;

    @Autowired
    private ShopService shopService;
    @Autowired
    private RoleService roleService;

    @Value("${face.server.host}")
    private String serverHost;

    @Transactional(rollbackFor = Exception.class)
    public void register(Account account) {
        Account existAccount = accountDao.findByUsername(account.getUsername());
        if (existAccount != null) {
            throw new AccountExistException("用户名已存在");
        }
        existAccount = accountDao.findByEmail(account.getEmail());
        if (existAccount != null) {
            throw new EmailExistException("邮箱已存在");
        }
        account.setShopId(UUID.randomUUID().toString().split("-")[0].toUpperCase());
        account.setActiveCode(UUID.randomUUID().toString());
        account.setStatus(1);
        account.setCreateTime(new Timestamp(System.currentTimeMillis()));
        account.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        Role role = new Role();
        role.setName("超级管理员");
        role.setDescription("超级管理员");
        role.setPermissions("[\"*\"]");
        role.setStatus(0);
        role.setCreatetime(new Date());
        role.setUpdatetime(new Date());
        role.setShopId(account.getShopId());
        role.setEnableNotify(0);
        Integer roleId = roleService.save(role);
        account.setRoleId(roleId);
        account.setType(1);
        accountDao.save(account);
        Shop shop = new Shop();
        shop.setShopId(account.getShopId());
        shop.setDeviceId("123456");
        shop.setCreateTime(new Timestamp(System.currentTimeMillis()));
        shop.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        shopService.save(shop);
        ThreadUtil.execute(() -> sendEmail(account));
    }

    public void sendEmail(Account account) {
        String emailMsg = "激活链接：<a href='"+serverHost+"/#/shop-info?activeCode="+account.getActiveCode()+"'>"+serverHost+"/#/shop-info?activeCode="+account.getActiveCode()+"</a>";
        String title = "用户激活";
        try {
            MailUtil.sendMail(account.getEmail(),title, emailMsg);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }

    public void active(String activeCode) {
        accountDao.active(activeCode);
    }

    public Account findByEmail(String email) {
        return accountDao.findByEmail(email);
    }

    public AccountWrapper findByUsernameAndPassword(String username, String password) {
        AccountWrapper account = accountDao.findByUsername(username);
        if (account == null || !account.getPassword().equals(password)) {
            throw new NoAccountException("账号或密码错误");
        }
        return account;
    }

    public Page<AccountWrapper> list(String shopId, Integer page, Integer limit, String username, String realname, Integer roleId, String order) {
        if (roleId!=null){
            return accountDao.listByRoleId(shopId,page,limit,username,realname,roleId,order);
        }

        if ((username == null || username.isEmpty()) && (realname == null || realname.isEmpty())) {
            return accountDao.listAll(shopId, page, limit, order);
        }
        return accountDao.list(shopId, page, limit, username, realname, order);
    }

    public Integer updateAccount(Account account){
        return accountDao.updateAccount(account);
    }

    public Integer resetPassword(String username){
        return accountDao.resetPassword(username);
    }

    @Transactional(rollbackFor = Exception.class)
    public String saveAccount(Account account) {
        account.setCreateTime(new Timestamp(System.currentTimeMillis()));
        Account existAccount = accountDao.findByUsername(account.getUsername());
        if (existAccount != null) {
            throw new AccountExistException("用户名已存在");
        }
        account.setType(2);
        return accountDao.saveAccount(account);
    }

    public Account findByUsername(String username) {
        Account account = accountDao.findByUsername(username);
        if (account == null) {
            return null;
        }
        account.setEmail(null);
        account.setMobilephone(null);
        account.setActiveCode(null);
        account.setStatus(null);
        return account;
    }

    public Integer deleteAccount(String username){
        return accountDao.deleteAccount(username);
    }

    public List<String> findEnableNotifyOpenids(String shopId) {
        return accountDao.findEnableNotifyOpenids(shopId);
    }

    public void changePassword(ChangePasswordForm form) {
        try {
            this.findByUsernameAndPassword(form.getUsername(), form.getOldPassword());
        } catch (NoAccountException e) {
            throw new OldPasswordErrorException("原密码错误");
        }
        accountDao.changePassword(form.getUsername(), form.getNewPassword());

    }

    public Account findByActiveCode(String activeCode) {
        Account account = accountDao.findByActiveCode(activeCode);
        return account;
    }

    public void updateStatus(String shopId, int status) {
        accountDao.updateStatus(shopId, status);
    }

    public void updateStatusByUsername(String username, int status) {
        accountDao.updateStatusByUsername(username, status);

    }

    public Integer updateAccountWeixin(String username, String openId ) {
        return accountDao.updateAccountWeixin(username, openId );
    }

    public List<Account> findAllByShopId(String shopId) {
        return accountDao.findAllByShopId(shopId);
    }

    public String findUsernameByOpenid(String openid){
        return accountDao.findUsernameByOpenid(openid);
    }

    public List<Account> findByRoleId(Integer roleId) {
        return accountDao.findByRoleId(roleId);
    }

    public Account findManagerByShopId(String shopId) {
        return accountDao.findManagerByShopId(shopId);
    }
}
